﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

using System.Windows.Media.Animation;




namespace BadHabit.Factory.Controls {

    /// <summary>
    /// Interaction logic for PostItListBox.xaml
    /// </summary>
    public partial class TaskPostItViewer : TaskViewerBase {

        protected System.Data.DataView FilteredView { get; set; }
       
        /// <summary>
        /// Default Construvtor.
        /// </summary>      
        public TaskPostItViewer() {
            InitializeComponent();            
        }

        /// <summary>
        /// If is not a TO DO Panel, do not show the context menu.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e) {
            if(!TaskStatus.TASK_REQUIRED.Equals(TaskStatusFilter))
                listBox.ContextMenu = null;

            
        }      


        #region Drag & drop Methods

        private void listBox_Drop(object sender, DragEventArgs e) {

            if (draggingPostIt != null)
                draggingPostIt.Cursor = PanCursor;

            
            

            if (!e.Data.GetDataPresent(typeof(Data.TaskDataSet.TaskRow)))
                return;

            Data.TaskDataSet.TaskRow taskRow = (Data.TaskDataSet.TaskRow)e.Data.GetData(typeof(Data.TaskDataSet.TaskRow));


            if (!VerifyTaskChangePermission(taskRow))
                return;

            taskRow.Status = (short)TaskStatusFilter;

            // could not figure out a better way
            foreach (System.Data.DataRowView taskRowView in FilteredView) {
                if (taskRowView["TaskUId"].Equals(taskRow.TaskUId)) {
                    listBox.Items.MoveCurrentTo(taskRowView);
                    SetPostItFocus();
                    break;
                }
            }
            
            
            


        }

        
        /// <summary>
        /// When post id is loaded attached the drag n drop handle.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void postItBorder_Loaded(object sender, RoutedEventArgs e) {

            // get the element and the data
            FrameworkElement element = sender as FrameworkElement;

            Data.TaskDataSet.TaskRow taskRow = Helper.GetRowFromRowView<Data.TaskDataSet.TaskRow>(element.DataContext);
            if (taskRow == null)
                return;

            DataObject data = new DataObject();
            data.SetData(taskRow);

            // creates the handle
            BadHabit.WPFTools.DragDropHandler dragDropH = new BadHabit.WPFTools.DragDropHandler(element, data);
            
            
            
        }





        #endregion


        

        /// <summary>
        /// Creates a view with only the task of the post it panel statsu filter.
        /// </summary>
        /// <param name="tasks">Tasks table</param>
        /// <returns>DataView with the tasks</returns>
        protected void CreateFilteredView(Data.TaskDataSet.TaskDataTable tasks) {

            FilteredView = tasks.DataSet.DefaultViewManager.CreateDataView(tasks);
            listBox.ItemsSource = FilteredView;
            
            
        }


        private void TaskViewerBase_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) {
            if (!(DataContext is Data.TaskDataSet.TaskDataTable))
                return;
            CreateFilteredView((Data.TaskDataSet.TaskDataTable)DataContext);            
            ApplyFilter();
        }

        /// <summary>
        /// Applies the filter on th listbox.
        /// </summary>        
        protected override void ApplyFilter() {

            if (FilteredView == null)
                return;

            string statusFilterString = "";


            if (TaskStatus.TASK_REQUIRED.Equals(TaskStatusFilter))
                statusFilterString = FilterString + " AND (Status=" + (short)TaskStatus.TASK_REQUIRED + " or Status=" + (short)TaskStatus.CREATION + ")";

            if (TaskStatus.TASK_WORKINGON.Equals(TaskStatusFilter))
                statusFilterString = FilterString + " AND (Status=" + (short)TaskStatus.TASK_WORKINGON + " or Status=" + (short)TaskStatus.TASK_VALIDATING + ")";

            if (TaskStatus.TASK_DONE.Equals(TaskStatusFilter))
                statusFilterString = FilterString + " AND (Status=" + (short)TaskStatus.TASK_DONE + " or Status=" + (short)TaskStatus.TASK_CANCELED + ")";


            FilteredView.RowFilter = statusFilterString;

            Data.TaskDataSet.TaskDataTable taskTable = DataContext as Data.TaskDataSet.TaskDataTable;
            if (taskTable == null)
                return;

            object count = taskTable.Compute("COUNT(TaskId)", statusFilterString);
            object sum = taskTable.Compute("SUM(PlannedEffort)", statusFilterString);
            if (count != null && count != System.DBNull.Value)
                SetValue(TaskCountKey, count);
            if (sum != null && sum != System.DBNull.Value)
                SetValue(TaskHourCountKey, sum);
        }
                


        /// <summary>
        /// Context menu action for new task creation.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NewTaskMenuItem_Click(object sender, RoutedEventArgs e) {
            MenuItem item = sender as MenuItem;
            switch (item.Name) {
                case "newTaskMenuItem":
                    AddNewTask(TaskTypes.PROJECT_TASK);
                    break;
                case "newTestTaskMenuItem":
                    AddNewTask(TaskTypes.TEST_TASK);
                    break;
                case "newBugMenuItem":
                    AddNewTask(TaskTypes.DEVELOPING_BUG);
                    break;
                case "newADBugMenuItem":
                    AddNewTask(TaskTypes.AFTER_DELIVERY_BUG);
                    break;
                case "newImpedimentMenuItem":
                    AddNewTask(TaskTypes.IMPEDIMENT);
                    break;
            }
                        
        }


        /// <summary>
        /// Adds a new task from a given type.
        /// </summary>
        /// <param name="type">The task type.</param>
        private Data.TaskDataSet.TaskRow AddNewTask(TaskTypes type) {

            if (!CanAddTask())
                return null;

            // creates the row at the dataset
            System.Data.DataView view = listBox.ItemsSource as System.Data.DataView;
            Data.TaskDataSet.TaskDataTable taskTable = view.Table as Data.TaskDataSet.TaskDataTable;

            Data.TaskDataSet.TaskRow newTask = taskTable.NewTaskRow();

            SetDefaultTaskValues(newTask);
            newTask.TaskType = (short)type;

            taskTable.AddTaskRow(newTask);

            listBox.Items.MoveCurrentToLast();
            listBox.ScrollIntoView(listBox.Items.CurrentItem);

            SetPostItFocus();
            
            return newTask;
        }

        private void SetPostItFocus() {

            if (listBox.Items.CurrentItem == null)
                return;

            ListBoxItem item = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(listBox.Items.CurrentItem);
            item.ApplyTemplate();
            ContentPresenter cp = Helper.GetObjectOfTypeInVisualTree<ContentPresenter>(item);

            if (cp == null)
                return;

            DataTemplate itemTemplate = (DataTemplate)this.Resources["PostItTemplate"];
            cp.ApplyTemplate();
            TextBox taskNameTextBox = itemTemplate.FindName("taskNameTextBox", cp) as TextBox;
            if (taskNameTextBox != null)
                taskNameTextBox.Focus();

        }





        /// <summary>
        /// Cancel a task.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CancelTaskMenuItem_Click(object sender, RoutedEventArgs e) {
            MenuItem item = sender as MenuItem;            
            Data.TaskDataSet.TaskRow task = Helper.GetRowFromRowView<Data.TaskDataSet.TaskRow>(item.DataContext);
            task.Status = (short)TaskStatus.TASK_CANCELED;
        }


        /// <summary>
        /// When user selects a unit, closes the drop down also.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UnitNameComboBox_DropDownClosed(object sender, EventArgs e) {
            ComboBox c = sender as ComboBox;
            if (c == null)
                return;
            MenuItem item = c.Parent as MenuItem;
            if (item == null)
                return;
            ContextMenu menu = item.Parent as ContextMenu;
            if (menu == null)
                return;
            menu.IsOpen = false;
          
        }


        private Data.ProjectDataSet.ProjectRow Project {
            get {
                if (Client.FactoryMainWindow.tabControl.DataContextAsProjectDataSet == null)
                    return null;
                if (Client.FactoryMainWindow.tabControl.DataContextAsProjectDataSet.Project.Count == 0)
                    return null;
                return Client.FactoryMainWindow.tabControl.DataContextAsProjectDataSet.Project[0];
            }
        }

        private void tailLookMenuItem_Click(object sender, RoutedEventArgs e) {
            MenuItem item = sender as MenuItem;
            if (item == null)
                return;
            TaskPanelBase.OpenTaskTailWindow(Helper.GetRowFromRowView<Data.TaskDataSet.TaskRow>(item.DataContext));            
        }


        /// <summary>
        /// Moves the TextBox value 0.5 up or down.
        /// We dont have a NumericUpDown at WPF, so this is a simple work around.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TextBox_KeyUp(object sender, KeyEventArgs e) {
            TextBox textBox = sender as TextBox;
            if (e.Key.Equals(Key.Up)) {
                double d = 0.0;
                if (Double.TryParse(textBox.Text, out d))
                    textBox.Text = (d + 0.5).ToString("F1");
            }
            if (e.Key.Equals(Key.Down)) {
                double d = 0.0;
                if (Double.TryParse(textBox.Text, out d))
                    if(d>=0.5)
                        textBox.Text = (d - 0.5).ToString("F1");
            }

        }

        public override void PasteTasks(string[] tasks) {

            if (!CanAddTask())
                return;

            if (this.TaskStatusFilter != TaskStatus.TASK_REQUIRED)
                return;

            foreach (string taskName in tasks) {
                Data.TaskDataSet.TaskRow newTask = AddNewTask(TaskTypes.PROJECT_TASK);
                if(newTask!=null)
                    newTask.TaskName = taskName;

            }

        }

       

        private Cursor PanDownCursor {
            get {
                Control panDownCursorMock = Resources["PanDownCursorMock"] as Control;
                return panDownCursorMock.Cursor;
            }
        }

        private Cursor PanCursor {
            get {
                Control panCursorMock = Resources["PanCursorMock"] as Control;
                return panCursorMock.Cursor;
            }
        }

        private void postItBorder_GiveFeedback(object sender, GiveFeedbackEventArgs e) {
            if (e.Effects == DragDropEffects.None) {
                e.UseDefaultCursors = true;
            } else {
                Mouse.SetCursor(PanDownCursor);
                e.UseDefaultCursors = false;
            }
            e.Handled = true;
        }

        FrameworkElement draggingPostIt = null;
        

        private void postItBorder_MouseDown(object sender, MouseButtonEventArgs e) {
            draggingPostIt = sender as FrameworkElement;        
            draggingPostIt.Cursor = PanDownCursor;
        }

        private void postItBorder_MouseUp(object sender, MouseButtonEventArgs e) {            
            if(draggingPostIt!=null)
                draggingPostIt.Cursor = PanCursor;
        }


        private void ViewTaskTailCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) {
            Data.TaskDataSet.TaskRow task = Helper.GetRowFromRowView<Data.TaskDataSet.TaskRow>(((System.Windows.Controls.Control)e.OriginalSource).DataContext);
            if (task == null)
                return;
            TaskPanelBase.OpenTaskTailWindow(task);
        }

        
      


        private void CancelTaskCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) {
            Data.TaskDataSet.TaskRow task = Helper.GetRowFromRowView<Data.TaskDataSet.TaskRow>(((System.Windows.Controls.Control)e.OriginalSource).DataContext);
            if (task == null)
                return;

            if (!VerifyTaskChangePermission(task))
                return;

            task.Status = (short)TaskStatus.TASK_CANCELED;


        }

        private void DoneTaskCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) {
            Data.TaskDataSet.TaskRow task = Helper.GetRowFromRowView<Data.TaskDataSet.TaskRow>(((System.Windows.Controls.Control)e.OriginalSource).DataContext);
            if (task == null)
                return;

            if (!VerifyTaskChangePermission(task))
                return;

            task.Status = (short)TaskStatus.TASK_DONE;
        }

        private void MoveTaskCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) {
            Data.TaskDataSet.TaskRow task = Helper.GetRowFromRowView<Data.TaskDataSet.TaskRow>(((System.Windows.Controls.Control)e.OriginalSource).DataContext);
            if (task == null)
                return;

            if (!VerifyTaskChangePermission(task))
                return;


            System.Data.DataRowView backlogItem = e.Parameter as System.Data.DataRowView;
            if (backlogItem == null)
                return;
            TaskPanelBase.MoveTask(task, backlogItem["SprintUId"].ToString(), backlogItem["BacklogItemUId"].ToString(), (short)backlogItem["BacklogItemNumber"], true);
        }

        private void UnitChangeTaskCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) {
            // DONT NEED TO DO NOTHING HERE THE DATACONTEXT WORKS FOR IT SELF
            return;
        }

        private void IsPayableChangeTaskCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) {
            // DONT NEED TO DO NOTHING HERE THE DATACONTEXT WORKS FOR IT SELF
            return;
        }

      
        public void AddTask_Executed(object sender, ExecutedRoutedEventArgs e) {            
            TaskTypes type = TaskTypes.PROJECT_TASK;

            if(e.Parameter!=null)
                type = (TaskTypes)  Enum.Parse(typeof(TaskTypes), e.Parameter.ToString());

            AddNewTask(type);
        }

        private void AddTaskMaterial_Executed(object sender, ExecutedRoutedEventArgs e) {
            Data.TaskDataSet.TaskRow task = Helper.GetRowFromRowView<Data.TaskDataSet.TaskRow>(((System.Windows.Controls.Control)e.OriginalSource).DataContext);
            if (task == null)
                return;
            if (!VerifyAddTaskMaterial(task))
                return;
            AddTaskMaterial(task.TaskUId, Client.FactoryMainWindow.tabControl.Project.ProjectDocBase, false);
        }

        private void AddTaskMaterialLink_Executed(object sender, ExecutedRoutedEventArgs e) {
            Data.TaskDataSet.TaskRow task = Helper.GetRowFromRowView<Data.TaskDataSet.TaskRow>(((System.Windows.Controls.Control)e.OriginalSource).DataContext);
            if (task == null)
                return;
            if (!VerifyAddTaskMaterial(task))
                return;
            AddTaskMaterial(task.TaskUId, Client.FactoryMainWindow.tabControl.Project.ProjectDocBase, true);
        }

        private void Hyperlink_Click(object sender, RoutedEventArgs e) {
            Hyperlink link = sender as Hyperlink;
            if (link == null)
                return;
            TaskView.MoveCurrentTo(link.DataContext);
            Windows.TaskDetail w = new BadHabit.Factory.Windows.TaskDetail(Client.FactoryMainWindow.CurrentProject, TaskView);
            w.Show();
        }


        public BindingListCollectionView TaskView {
            get {
                return (BindingListCollectionView)CollectionViewSource.GetDefaultView(listBox.ItemsSource);
            }
        }
    
    }
}
